from games.basegame import BaseGame, activeGames
from framework.result import Result

class TicTacToe(BaseGame):
	def __init__(self):
		BaseGame.__init__(self, 2, 2)
		self.board = [None] * 9
		self.winner = None
		self.gameType = 'TicTacToe'
		self.playerSigns = {}
		self.availableSigns = ['O', 'X']
		self.orderOfPlay = []

		# store this game in temporary memory
		if not self.gameType in activeGames:
			activeGames[self.gameType] = {}
		activeGames[self.gameType][self.id] = self

		# determine all winning combinations
		self.winningCombinations = [
			[1,2,3],[4,5,6],[7,8,9],
			[1,4,7],[2,5,8],[3,6,9],
			[1,5,9],[3,5,7]
		]

	def isWinningList(self, list):
		return not list[0] is None and list == [list[0]] * len(list)

	def __checkGameOver__(self):
		# check if anybody won
		for combination in self.winningCombinations:
			if self.isWinningList([self.board[i-1] for i in combination]):
				self.winner = self.board[combination[0]]
				return True

		# if no winners, check if there is still room to play
		for space in self.board:
			if space is None:
				return False

		# if we got here, there's no room to play and no winner
		self.winner = 'the cats'
		return True

	def move(self, userId, spaceAsString):
		if not self.started:
			return Result(Result.NotPossible, 'game not started')
		if not self.orderOfPlay[0] == userId:
			return Result(Result.NotPossible, 'not your move')

		space = int(spaceAsString)
		if self.__checkGameOver__():
			return Result(Result.NotPossible, 'game already ended')
		else:
			if self.board[space] is None:
				self.board[space] = userId
				# announce the move
				self.sendBroadcastMessage(self.players[userId], {
					'action': 'moved',
					'moveFrom': self.playerPositions[userId],
					'moveSign': self.playerSigns[userId],
					'moveSpace': spaceAsString
				}, True)
				# next player's move
				self.orderOfPlay.append(self.orderOfPlay.pop(0))
				if self.__checkGameOver__():
					return Result(Result.Success, self.winner + ' won')
				else:
					return Result(Result.Success)
			else:
				return Result(Result.NotPossible, 'illegal move')

	def addPlayer(self, player):
		if self.started:
			return Result(Result.NotPossible, 'game already started')

		result = BaseGame.addPlayer(self, player)
		if result == Result.Success:
			if player.id not in self.playerSigns:
				self.playerSigns[player.id] = self.availableSigns.pop()
				self.orderOfPlay.append(player.id)
				# announce the move
				self.sendBroadcastMessage(self.players[player.id], {
					'action': 'joined',
					'playerNickname': player.nickname,
					'playerSign': self.playerSigns[player.id]
				}, True)
				if len(self.players) >= self.minimumPlayers:
					self.startGame()
			else:
				result = Result(Result.NotPossible, 'player already joined this game')

		return result
